import * as Cesium from 'cesium'
class LineSpaceMeasurement {
  constructor(arg) {
    if (!arg.viewer) throw new Error('Viewer 实例必须提供');

    this.viewer = arg.viewer;
    this.Cesium = arg.Cesium || Cesium;
    if (!this.Cesium) {
      if (typeof Cesium === 'undefined') {
        throw new Error('Cesium 库未正确加载，请检查 HTML 文件中是否引入了 Cesium 库。');
      }
      this.Cesium = Cesium;
    }
    this.distanceHandler = null;
    this.positions = [];
    this.polyline = null;
    this.pointEntities = [];
    this.isActive = false;
  }

  /**
   * 开始空间直线距离测量
   */
  start() {
    if (this.isActive) return;
    this.clear();
    this.isActive = true;
    if (this.viewer.cesiumWidget) {
      this.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
        this.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
      );
    }

    // 取消双击事件-追踪该位置


    this.distanceHandler = new this.Cesium.ScreenSpaceEventHandler(
      this.viewer.scene._imageryLayerCollection
    );

    // 鼠标移动事件
    this.distanceHandler.setInputAction((movement) => {
      const cartesian = this._getCartesianFromPosition(movement.endPosition);
      if (!cartesian) return;

      if (this.positions.length >= 2) {
        if (!this.polyline) {
          this.polyline = new PolyLinePrimitive(this.positions, this.viewer, this.Cesium);
        } else {
          this.positions.pop();
          this.positions.push(cartesian);
        }

        const distance = this._getSpaceDistance(this.positions);
        // 可触发外部事件或更新UI
      }
    }, this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    // 左键点击事件
    this.distanceHandler.setInputAction((movement) => {
      const cartesian = this._getCartesianFromPosition(movement.position);
      if (!cartesian) return;

      if (this.positions.length === 0) {
        this.positions.push(cartesian.clone());
      }

      this.positions.push(cartesian);

      // 添加距离标签
      const distance = this._getSpaceDistance(this.positions);
      const pointEntity = this._createDistanceLabel(cartesian, distance);
      this.pointEntities.push(pointEntity);
    }, this.Cesium.ScreenSpaceEventType.LEFT_CLICK);

    // 右键点击事件
    this.distanceHandler.setInputAction(() => {
      this.stop();
    }, this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  /**
   * 停止测量
   */
  stop() {
    if (!this.isActive) return;

    if (this.distanceHandler) {
      this.distanceHandler.destroy();
      this.distanceHandler = null;
    }

    if (this.positions.length > 0) {
      this.positions.pop(); // 最后一个点无效
    }

    this.isActive = false;
  }

  /**
   * 清除测量结果
   */
  clear() {
    this.stop();

    // 移除所有实体
    this.pointEntities.forEach(entity => {
      this.viewer.entities.remove(entity);
    });

    if (this.polyline) {
      this.polyline.destroy();
      this.polyline = null;
    }

    this.positions = [];
    this.pointEntities = [];
  }

  /**
   * 从屏幕位置获取地形坐标
   * @private
   */
  _getCartesianFromPosition(position) {
    const ray = this.viewer.camera.getPickRay(position);
    return this.viewer.scene.globe.pick(ray, this.viewer.scene);
  }

  /**
   * 创建距离标签实体
   * @private
   */
  _createDistanceLabel(position, distance) {
    return this.viewer.entities.add({
      name: '空间直线距离',
      position: position,
      point: {
        pixelSize: 4,
        color: this.Cesium.Color.RED,
        outlineColor: this.Cesium.Color.WHITE,
        outlineWidth: 2,
      },
      label: {
        text: `${distance}米`,
        font: '18px sans-serif',
        fillColor: this.Cesium.Color.GOLD,
        style: this.Cesium.LabelStyle.FILL_AND_OUTLINE,
        outlineWidth: 2,
        verticalOrigin: this.Cesium.VerticalOrigin.BOTTOM,
        pixelOffset: new this.Cesium.Cartesian2(20, -20),
      }
    });
  }

  /**
   * 计算空间距离
   * @private
   */
  _getSpaceDistance(positions) {
    let distance = 0;

    for (let i = 0; i < positions.length - 1; i++) {
      const point1Cartographic = this.Cesium.Cartographic.fromCartesian(positions[i]);
      const point2Cartographic = this.Cesium.Cartographic.fromCartesian(positions[i + 1]);

      // 计算地表距离
      const geodesic = new this.Cesium.EllipsoidGeodesic();
      geodesic.setEndPoints(point1Cartographic, point2Cartographic);
      let s = geodesic.surfaceDistance;

      // 考虑高度差的三维距离
      s = Math.sqrt(
        Math.pow(s, 2) +
        Math.pow(point2Cartographic.height - point1Cartographic.height, 2)
      );

      distance += s;
    }

    return distance.toFixed(2);
  }
}

/**
 * 辅助类：动态更新的折线
 */
class PolyLinePrimitive {
  constructor(positions, viewer, Cesium) {
    this.positions = positions;
    this.viewer = viewer;
    this.Cesium = Cesium;
    this.entity = null;
    this._init();
  }

  _init() {
    let _this = this;
    const updatePositions = () => this.positions;

    this.entity = this.viewer.entities.add({
      name: '直线',
      polyline: {
        show: true,
        positions: new this.Cesium.CallbackProperty(updatePositions, false),
        material: this.Cesium.Color.CHARTREUSE,
        width: 2,
        clampToGround: true
      }
    });
  }

  destroy() {
    if (this.entity) {
      this.viewer.entities.remove(this.entity);
      this.entity = null;
    }
  }
}

export default LineSpaceMeasurement;